package com.wl.dzt.ide.service;


import com.wl.dzt.ide.dto.ClassField;
import com.wl.dzt.sys.core.dao.db.DBColumn;
import com.wl.dzt.sys.core.dao.db.DBMate;
import com.wl.dzt.sys.core.dao.db.DBTable;
import com.wl.dzt.sys.core.dao.mate.DataMateBase;
import com.wl.dzt.sys.core.dao.tree.TreeBuilder;
import com.wl.dzt.sys.core.dao.tree.TreeSetting;
import com.wl.dzt.sys.fmk.Fmkr;
import com.wl.dzt.sys.util.StringUtil;
import com.wl.dzt.sys.util.SystemUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.sql.SQLException;
import java.util.*;

/**
 * @author wl_code@163.com
 * @version 1.0
 * @date 2018/7/5/005
 * @description 实体构建服务
 */
@Service
public class EntityGeneratorService {


    /**
     * 数据信息
     */
    @Resource
    private DBMate dbMate;

    /**
     * 数据类型映射
     */
    private static Map<String, Object> TYPES = new HashMap<>();

    static {
        TYPES.put("varchar", "String");
        TYPES.put("nvarchar", "String");
        TYPES.put("varchar2", "String");
        TYPES.put("nvarchar(max)", "String");
        TYPES.put("text", "String");
        TYPES.put("int", "Integer");
        TYPES.put("double", "Double");
        TYPES.put("datetime2", "Date");
        TYPES.put("date", "Date");
        TYPES.put("datetime", "Date");
        TYPES.put("decimal", "Double");
        TYPES.put("float", "Double");
        TYPES.put("longtext", "String");
    }

    /**
     * <b>查询表格</b>
     * <p>
     * 根据表名查询表格
     * </p>
     *
     * @throws SQLException
     */
    public List<Map<String, Object>> allTable() throws SQLException {
        return TreeBuilder.cascadeTree(dbMate.getTables(), TreeSetting.createByExp("tableName,tableName,*"));
    }

    /**
     * <b>根据表名查询字段</b>
     * <p>
     * 根据表名查询字段
     * </p>
     *
     * @param tableName
     * @return
     * @throws SQLException
     */
    public List<DBColumn> allCols(String tableName) throws SQLException {
        DBTable dbTable = dbMate.getTable(tableName);
        List<DBColumn> columns = new ArrayList<>();
        dbTable.getColumns().keySet().forEach(key -> columns.add(dbTable.getColumns().get(key)));
        columns.sort(Comparator.comparing(DBColumn::getColumnName));
        return columns;
    }

    /**
     * <b>创建类字段</b>
     * <p>
     * 创建类字段
     * </p>
     *
     * @return
     * @throws SQLException
     */
    public List<ClassField> createClassFields(String tableName) throws SQLException {
        DBTable dbTable = dbMate.getTable(tableName);
        List<ClassField> list = new ArrayList<>();
        dbTable.getColumns().keySet().forEach(key -> {
            DBColumn column = dbTable.getColumns().get(key);
            ClassField classField = new ClassField();
            classField.setCn(column.getRemarks());
            classField.setDataBaseName(column.getColumnName());
            classField.setName(StringUtil.hump(column.getColumnName()));
            classField.setMaxLength(column.getSize() / 2);
            classField.setType(TYPES.get(column.getColumnType().toLowerCase()) + "");
            classField.setRefClass(column.getRefTable() == null ? null : StringUtil.hump(column.getRefTable()));
            classField.setMethodName(StringUtil.firstCharacterToUpper(classField.getName()));
            if (column.getSize() == 32) {
                classField.setMaxLength(32);
            } else if (column.getSize() == 0) {
                classField.setMaxLength(200);
            }
            list.add(classField);
        });
        return list;
    }

    /**
     * <b>创建实体</b>
     * <p>
     * 创建实体
     * </p>
     *
     * @param tables 表格
     * @throws SQLException sql异常
     */
    public void createEntity(String[] tables, String pack) throws Exception {
        File folder = new File(SystemUtil.getDasktopPath() + "/" + pack);
        folder.mkdir();
        for (String table : tables) {
            Map<String, Object> data = new HashMap<>();
            Map<String, String> impl = new HashMap<>();
            List<String> impls = new ArrayList<>();
            List<ClassField> classFields = createClassFields(table);
            classFields.forEach(field -> {
                if (field.getType().equals("Date")) {
                    impl.put("import java.util.Date", "import java.util.Date");
                }
                if (field.getRefClass() != null) {
                    field.setType(StringUtil.firstCharacterToUpper(field.getRefClass()));
                    field.setMethodName(StringUtil.firstCharacterToUpper(field.getName()));
                    Class<?> clazz = DataMateBase.DATA_TABLE_CLASS.get(field.getType());
                    String implKey = "";
                    if (!clazz.getSimpleName().equals(StringUtil.firstCharacterToUpper(StringUtil.hump(table)))) {
                        String.format("import %s.%s", pack, field.getType());
                    }
                    if (clazz != null && !clazz.getSimpleName().equals(StringUtil.firstCharacterToUpper(StringUtil.hump(table)))) {
                        implKey = "import " + clazz.getName();
                    }
                    impl.put(implKey, implKey);
                }
            });
            impl.forEach((key, val) -> impls.add(key));
            data.put("pack", "package " + pack);
            data.put("impls", impls);
            data.put("classFields", classFields);
            data.put("className", StringUtil.firstCharacterToUpper(StringUtil.hump(table)));
            data.put("tableName", table);

            //默认寻找template目录
            Fmkr.builder("ide/javabean.ftl", data,
                    String.format("%s/%s/%s.java", SystemUtil.getDasktopPath(), pack, data.get("className")));
        }
    }
}
